package perso;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;

import actions.Action;

import module.ModuleMobilePerso;
import module.ModuleStateImp;
import module.ModuleStateImpG;

import motor.MotorPerso;
import motor.Unite;

import utils.Vector2d;

public class Groupe
{
	public ArrayList<Unite> interne = new ArrayList<Unite>();
	public Vector2d bary = new Vector2d();
	
	int	sizePerso = 4;
	int sizeColli = 10;
	int disInterne = 25;
	
	int marge = 3;
	
	private Vector2d	vtemp = new Vector2d(-1, -1);
	
	float vmin = (float) 2;
	
	ModuleStateImpG mstate;
	
	Action action;

	public Action getAction()
	{
		return action;
	}

	public void setAction(Action action)
	{
		this.action = action;
	}

	public void add(Unite u)
	{
		interne.add(u);
		
		miseAJour();
	}

	private void miseAJour()
	{
		bary.x = 0;
		bary.y = 0;
		
		for( int i = 0 ; i < interne.size() ; i++ )
		{
			bary.x += interne.get(i).getPos().x;
			bary.y += interne.get(i).getPos().y;
		}
		
		bary.x /= interne.size();
		bary.y /= interne.size();
	}

	private Vector2d control()
	{
		Vector2d a = new Vector2d(-1, -1);
		
		a.x = 0;
		a.y = 0;
		
		for( int i = 0 ; i < interne.size() ; i++ )
		{
			a.x += interne.get(i).getPos().x;
			a.y += interne.get(i).getPos().y;
		}
		
		a.x /= interne.size();
		a.y /= interne.size();
		
		return a;
	}
	
	
	
	public float distance(Vector2d point)
	{
		return (float) Math.sqrt(Math.pow(bary.x-point.x, 2 ) + Math.pow(bary.y-point.y, 2 ));
	}

	public void draw(Graphics buffer_canvas)
	{
		for( int i = 0 ; i < interne.size() ; i++ )
		{
			interne.get(i).draw(buffer_canvas);
		}
		
		buffer_canvas.setColor( Color.BLUE );

		buffer_canvas.fillOval((int)(bary.x-sizePerso/2), (int)(bary.y-sizePerso/2), sizePerso , sizePerso);

	}

	public void prepareMove(MotorPersoImp m )
	{
		ArrayList<Groupe> voisinsG = new ArrayList<Groupe>();

		for( int i = 0 ; i < m.populationPerso.size() ; i++ )
		{
			float dis = distance( m.populationPerso.get(i).bary );
			
			if( dis < sizeColli )
			{
				voisinsG.add( m.populationPerso.get(i) );
			}
		}
		
		//System.out.println("GT " + mstate.getType() );
		//System.out.println("Gbary " + bary );
		
		for( int i = 0 ; i < interne.size() ; i++)
		{
			//System.out.println("UT " + interne.get(i).mstate.getType() );
			//System.out.println("UM " + interne.get(i).mobile.getPos() );
			
			((ModuleMobilePerso)(interne.get(i).getMobile())).calVemp( bary );
			
			//System.out.println("Vtemp " + interne.get(i).mobile.getVtemp() );
		}
		
		
		for( int i = 0 ; i < interne.size() ; i++)
		{
			((ModuleMobilePerso)(interne.get(i).getMobile())).movePerso(m, voisinsG);
		}
		
		//miseAJour();
		vtemp.x = 0;
		vtemp.y = 0;
		
		if( action != null )
			action.avancement( vtemp , m );
		
		float xt = vtemp.x;
		float yt = vtemp.y;
		
		float val = (float) Math.sqrt(Math.pow(vtemp.x, 2 ) + Math.pow(vtemp.y, 2 ));
		
		if( val != 0 )
		{
			vtemp.x *= vmin/val;
			vtemp.y *= vmin/val;

			if( vtemp.x > 0 )
			{
				if( vtemp.x > xt )
					vtemp.x = xt;
			}	
			else 
			{
				if( vtemp.x > -xt )
					vtemp.x = -xt;
			}
			
			if( vtemp.y > 0 )
			{
				if( vtemp.y > yt )
					vtemp.y = yt;
			}	
			else 
			{
				if( vtemp.y > -yt )
					vtemp.y = -yt;
			}
			
			//System.out.println( yt + " -> " + vtemp.y );
			
			//System.out.println("Dis : " + control().distance(bary) );
			
			if( control().distance(bary) < disInterne )
			{	
				bary.x += vtemp.x;
				bary.y += vtemp.y;
			}
		}
		
		for( int i = 0 ; i < interne.size() ; i++)
		{
			float dis = interne.get(i).distance(bary);
			
			if( dis > sizeColli )
			{
				sizeColli = (int) dis;
			}
		}
		
		
	}

	public void goOn(MotorPersoImp motorPerso)
	{
		mstate.goOn( motorPerso );
	}
	
	public ModuleStateImpG getMs()
	{
		return mstate;
	}

	public void setMs(ModuleStateImpG ms)
	{
		this.mstate = ms;
	}

	public Vector2d getBary()
	{
		return bary;
	}

	public Vector2d getVtemp()
	{
		return vtemp;
	}

	public void setVtemp(Vector2d vtemp)
	{
		this.vtemp = vtemp;
	}

	public void setBary(Vector2d bary)
	{
		this.bary = bary;
	}
}
